﻿#include "Request.h"
#include "constant.h"
#include "models.h"
#include "database.h"
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkCookie>
#include <QNetworkCookieJar>
#include <QDateTime>
#include <QEventLoop>
#include <QTimer>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>


Request::Request(QObject *parent) : QObject(parent)
{

}
QNetworkAccessManager *Request::createNetworkManager(const QUrl &qurl){

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//    QNetworkCookieJar *cookieJar =  new QNetworkCookieJar(manager);
//    cookieJar->setCookiesFromUrl(networkManager->cookieJar()->cookiesForUrl(qurl),qurl);
//    manager->setCookieJar(cookieJar);
    return manager;
}


void Request::reportCrash(){

    /**
     * &buildCpuArchitecture=x86_64
     * &currentCpuArchitecture=x86_64
     * &machineUniqueId=f1ec52cd-6c2c-439b-9406-469d9476a089&bootUniqueId=
     * &prettyProductName=Windows 10 Version 2009
     * &productType=windows&buildAbi=x86_64-little_endian-llp64
     * &machineHostName=shisan
     * &kernelVersion=10.0.19044
     * &kernelType=winnt
     * &productVersion=10"
     **/

    QHash<QString,QString> params;

    params.insert("finger",Database::getInstance()->getFinger());
    params.insert("bootUniqueId",QSysInfo::bootUniqueId());
    params.insert("buildAbi",QSysInfo::buildAbi());
    params.insert("buildCpuArchitecture",QSysInfo::buildCpuArchitecture());
    params.insert("currentCpuArchitecture",QSysInfo::currentCpuArchitecture());
    params.insert("kernelType",QSysInfo::kernelType());
    params.insert("kernelVersion",QSysInfo::kernelVersion());
    params.insert("machineHostName",QSysInfo::machineHostName());
    params.insert("machineUniqueId",QSysInfo::machineUniqueId());
    params.insert("prettyProductName",QSysInfo::prettyProductName());
    params.insert("productType",QSysInfo::productType());
    params.insert("productVersion",QSysInfo::productVersion());

    QString url = HOST+"/reportCrash?version="+QCoreApplication::applicationVersion();

    QHash<QString,QString>::const_iterator it;
    for (it=params.constBegin();it!=params.constEnd();++it) {
        url +="&"+it.key()+"="+it.value();
    }
    qDebug()<<url;


    QUrl qurl(url);
    QNetworkRequest request(qurl);
    QNetworkAccessManager *manager = createNetworkManager(qurl);
    manager->get(request);

    connect(manager,&QNetworkAccessManager::finished, this,[manager](QNetworkReply *reply){
        reply->abort();
        reply->deleteLater();
        manager->deleteLater();

        QString msg;
        bool state = false;

        if(reply->error()!= QNetworkReply::NoError){
            msg = reply->errorString();
        }else {
            QJsonParseError jsonError;
            QJsonDocument document = QJsonDocument::fromJson(QString::fromUtf8(reply->readAll()).toUtf8(),&jsonError);
            if(jsonError.error!=QJsonParseError::NoError){
                msg = jsonError.errorString();
            }else {
                QJsonObject json = document.object();
                msg = json.value("msg").toString();
                state = json.value("code").toInt() == 1000?true:false;
            }
       }
        qDebug()<<state<<msg;

    });

}
void Request::reportHeart(uint32_t reportCount){
    QString url = QString("%1/reportHeart?version=%2&finger=%3&count=%4").
            arg(HOST).
            arg(QCoreApplication::applicationVersion()).
            arg(Database::getInstance()->getFinger()).arg(reportCount);
    QUrl qurl(url);
    QNetworkRequest request(qurl);
    QNetworkAccessManager *manager = createNetworkManager(qurl);
    manager->get(request);

    connect(manager,&QNetworkAccessManager::finished, this,[manager](QNetworkReply *reply){
        reply->abort();
        reply->deleteLater();
        manager->deleteLater();
    });
}

void Request::checkVersion(){

//    bool state = false;
//    QString msg = "当前是最新版本";
//    MVersion version;
//    version.version = QString("1.0").toFloat();
//    version.pubdate = "2023.3.16";
//    version.updateContent = "更新了，谢谢";
//    version.url = "https://gitee.com/Vanishi";
//    emit this->notifyGetVersion(state,msg,version);

    QHash<QString,QString> params;
    params.insert("finger",Database::getInstance()->getFinger());
    params.insert("bootUniqueId",QSysInfo::bootUniqueId());
    params.insert("buildAbi",QSysInfo::buildAbi());
    params.insert("buildCpuArchitecture",QSysInfo::buildCpuArchitecture());
    params.insert("currentCpuArchitecture",QSysInfo::currentCpuArchitecture());
    params.insert("kernelType",QSysInfo::kernelType());
    params.insert("kernelVersion",QSysInfo::kernelVersion());
    params.insert("machineHostName",QSysInfo::machineHostName());
    params.insert("machineUniqueId",QSysInfo::machineUniqueId());
    params.insert("prettyProductName",QSysInfo::prettyProductName());
    params.insert("productType",QSysInfo::productType());
    params.insert("productVersion",QSysInfo::productVersion());

    QString url = HOST+"/checkVersion?version="+QCoreApplication::applicationVersion();

    QHash<QString,QString>::const_iterator it;
    for (it=params.constBegin();it!=params.constEnd();++it) {
        url +="&"+it.key()+"="+it.value();
    }
    QUrl qurl(url);
    QNetworkRequest request(qurl);
    QNetworkAccessManager *manager = createNetworkManager(qurl);
    manager->get(request);

    connect(manager,&QNetworkAccessManager::finished, this,[this,manager](QNetworkReply *reply){
        reply->abort();
        reply->deleteLater();
        manager->deleteLater();

        MVersion version;
        bool state = false;
        QString msg = "未知错误";
        if(reply->error()!= QNetworkReply::NoError){
            msg = reply->errorString();
        }else {
            QJsonParseError jsonError;
            QJsonDocument document = QJsonDocument::fromJson(reply->readAll(),&jsonError);
            if(jsonError.error!=QJsonParseError::NoError){
                msg = jsonError.errorString();
            }else{
                QJsonObject json = document.object();
                msg = json.value("msg").toString();

                if(json.value("code").toInt() == 1000){
                    state = true;
                    QJsonObject data = json.value("data").toObject();
                    version.version = data.value("version").toString().toFloat();
                    version.pubdate = data.value("pubdate").toString();
                    version.updateContent = data.value("updateContent").toString();
                    version.url = data.value("url").toString();

                }
            }
        }
       emit this->notifyCheckVersion(state,msg,version);

    });

}

